package com.steakliu.sun.boot.starter;

import com.steakliu.sun.boot.starter.helper.ConfigInfoHelper;
import com.steakliu.sun.boot.starter.prop.*;
import com.steakliu.sun.client.SunClient;
import com.steakliu.sun.client.api.ClientConfig;
import com.steakliu.sun.configcenter.api.ConfigCenterConfig;
import com.steakliu.sun.configcenter.api.ConfigCenterService;
import com.steakliu.sun.configcenter.api.ConfigInfoTransfer;
import com.steakliu.sun.constant.SpringBootStarterConstant;
import com.steakliu.sun.server.SpringNettyServer;
import com.steakliu.sun.spi.loader.ExtensionLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 功能说明：
 * <p>
 * Original @Author: steakliu-刘牌, 2023-01-14  13:06
 * <p>
 * Copyright (C)2020-2022  steakliu All rights reserved.
 */
@Configuration
@EnableConfigurationProperties
public class SunSpringBootConfiguration {

    private final Logger LOGGER = LoggerFactory.getLogger(SunSpringBootConfiguration.class);

    @Bean
    @ConfigurationProperties(prefix = "sun.config")
    public ConfigCenterProperties configurationProperties() {
        return new ConfigCenterProperties();
    }

    /**
     * 启动服务端，按照条件进行装配，为true，那么启动服务端，false不启动
     * 当一个服务为服务消费者，本身不对外提供服务，那么就将open设置为true
     *
     * @return
     * @throws Exception
     */
    @Bean
    public SpringNettyServer springNettyServer(final ConfigCenterProperties properties) throws Exception {
        Prop prop = ConfigInfoHelper.getProp(properties);
        SunServerProperties serverProperties = prop.getSun().getServer();
        if (serverProperties.isOpen()) {
            return new SpringNettyServer(serverProperties.getHost(), serverProperties.getPort(), serverProperties.getRegistryType(),
                    serverProperties.getRegistryAddress(), serverProperties.getReflect(), serverProperties.getToken(),
                    serverProperties.getHeartbeatInterval(), serverProperties.getHeartbeatRetries(), serverProperties.getBossGroupThreads(),
                    serverProperties.getWorkGroupThreads(), serverProperties.isUseFlowControl(), serverProperties.getFlowControlType(),
                    serverProperties.getConcurrentCorePoolSize(), serverProperties.getConcurrentMaximumPoolSize(),
                    serverProperties.getMaxConnections(), serverProperties.getConnectionsDisuseStrategyType(),
                    serverProperties.isUseRateLimit(), serverProperties.getRateLimiterType(), serverProperties.getMilliseconds(),
                    serverProperties.getPermits(), serverProperties.getRateLimiterFailStrategy(), serverProperties.isEnableBuffer(),
                    serverProperties.getBufferType(),serverProperties.isEnableResultCache(), serverProperties.getResultCacheTime());
        }
        return null;
    }

    /**
     * 创建客户端SunClient
     * @return
     */
    @Bean
    public SunClient sunClient(final ConfigCenterProperties configCenterProperties) throws Exception {
        SunClientProperties clientProperties = ConfigInfoHelper.getProp(configCenterProperties).getSun().getClient();
        if (clientProperties.isOpen()) {
            ClientConfig clientConfig = ClientConfig.builder()
                    .version(clientProperties.getVersion())
                    .group(clientProperties.getGroup())
                    .registryType(clientProperties.getRegistryType())
                    .registryAddress(clientProperties.getRegistryAddress())
                    .serializer(clientProperties.getSerializer())
                    .proxy(clientProperties.getProxy())
                    .timeout(clientProperties.getTimeout())
                    .async(clientProperties.isAsync())
                    .oneway(clientProperties.isOneway())
                    .loadBalance(clientProperties.getLoadBalance())
                    .cache(clientProperties.isCache())
                    .cacheTime(clientProperties.getCacheTime())
                    .retries(clientProperties.getRetries())
                    .retryInterval(clientProperties.getRetryInterval())
                    .heartbeatRetries(clientProperties.getHeartbeatRetries())
                    .heartbeatInterval(clientProperties.getHeartbeatInterval())
                    .token(clientProperties.getToken())
                    .flowControlType(clientProperties.getFlowControlType())
                    .useFlowControl(clientProperties.isUseFlowControl())
                    .concurrentCorePoolSize(clientProperties.getConcurrentCorePoolSize())
                    .concurrentMaximumPoolSize(clientProperties.getConcurrentMaximumPoolSize())
                    .reflectType(clientProperties.getReflectType())
                    .useRateLimit(clientProperties.isUseRateLimit())
                    .rateLimiterType(clientProperties.getRateLimiterType())
                    .milliseconds(clientProperties.getMilliseconds())
                    .permits(clientProperties.getPermits())
                    .rateLimiterFailStrategy(clientProperties.getRateLimiterFailStrategy())
                    .enableBuffer(clientProperties.isEnableBuffer())
                    .bufferType(clientProperties.getBufferType())
                    .build();
            return new SunClient(clientConfig);
        }
        return null;
    }


}
